package com.scheduling.schedule.config;

import com.scheduling.schedule.algorithm.ScheduleAlgorithm;
import com.scheduling.schedule.enums.ScheduleAlgorithmType;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 排产算法配置类
 * 负责注册和管理所有排产算法实例
 *
 * @author 开发团队
 */
@Slf4j
@Configuration
public class ScheduleAlgorithmConfig {

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 算法映射表
     */
    private Map<String, ScheduleAlgorithm> algorithmMap;

    @PostConstruct
    public void init() {
        log.info("初始化排产算法映射...");

        algorithmMap = new HashMap<>();

        // 注册所有算法实例
        try {
            // 1.  增强遗传算法（基于工艺路线）（推荐）
            ScheduleAlgorithm enhancedGeneticAlgorithm = applicationContext.getBean("ENHANCED_GENETIC_ALGORITHM",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getCode(), enhancedGeneticAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getCode(),
                    ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getDescription());

            // 2.  关键路径法+SPT算法（推荐）
            ScheduleAlgorithm criticalPathSptAlgorithm = applicationContext.getBean("CRITICAL_PATH_SPT",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.CRITICAL_PATH_SPT.getCode(), criticalPathSptAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.CRITICAL_PATH_SPT.getCode(),
                    ScheduleAlgorithmType.CRITICAL_PATH_SPT.getDescription());


            // 3. 同种产品集中生产算法
            ScheduleAlgorithm productBatchAlgorithm = applicationContext.getBean("PRODUCT_BATCH",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.PRODUCT_BATCH.getCode(), productBatchAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.PRODUCT_BATCH.getCode(),
                    ScheduleAlgorithmType.PRODUCT_BATCH.getDescription());

            // 4. 机器利用率优先算法
            ScheduleAlgorithm machineUtilizationAlgorithm = applicationContext.getBean("MACHINE_UTILIZATION",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.MACHINE_UTILIZATION.getCode(), machineUtilizationAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.MACHINE_UTILIZATION.getCode(),
                    ScheduleAlgorithmType.MACHINE_UTILIZATION.getDescription());

            // 5. 默认FIFO算法（正式版本）
            ScheduleAlgorithm defaultFifoAlgorithm = applicationContext.getBean("DEFAULT_FIFO",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.DEFAULT_FIFO.getCode(), defaultFifoAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.DEFAULT_FIFO.getCode(),
                    ScheduleAlgorithmType.DEFAULT_FIFO.getDescription());

            // 6. COMBINE 算法
            ScheduleAlgorithm CombineAlgorithm = applicationContext.getBean("COMBINE_ALGORITHM",
                    ScheduleAlgorithm.class);
            algorithmMap.put(ScheduleAlgorithmType.COMBINE_ALGORITHM.getCode(), defaultFifoAlgorithm);
            log.info("注册算法: {} - {}", ScheduleAlgorithmType.COMBINE_ALGORITHM.getCode(),
                    ScheduleAlgorithmType.COMBINE_ALGORITHM.getDescription());

            log.info("排产算法初始化完成，共注册 {} 个算法", algorithmMap.size());

        } catch (Exception e) {
            log.error("算法注册失败", e);
            throw new RuntimeException("排产算法初始化失败", e);
        }
    }

    /**
     * 获取算法映射表Bean
     *
     * @return 算法映射表
     */
    @Bean("algorithmMap")
    public Map<String, ScheduleAlgorithm> getAlgorithmMap() {
        return algorithmMap;
    }

    /**
     * 根据算法类型获取算法实例
     *
     * @param algorithmType 算法类型
     * @return 算法实例
     */
    public ScheduleAlgorithm getAlgorithm(String algorithmType) {
        ScheduleAlgorithm algorithm = algorithmMap.get(algorithmType);
        if (algorithm == null) {
            throw new IllegalArgumentException("不支持的算法类型: " + algorithmType);
        }
        return algorithm;
    }

    /**
     * 获取所有支持的算法类型
     *
     * @return 算法类型列表
     */
    public String[] getSupportedAlgorithms() {
        return algorithmMap.keySet().toArray(new String[0]);
    }

    /**
     * 检查算法是否支持
     *
     * @param algorithmType 算法类型
     * @return 是否支持
     */
    public boolean isAlgorithmSupported(String algorithmType) {
        return algorithmMap.containsKey(algorithmType);
    }

    /**
     * 获取推荐算法列表
     *
     * @return 推荐算法类型数组
     */
    public String[] getRecommendedAlgorithms() {
        return new String[]{
                ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getCode(),
                ScheduleAlgorithmType.CRITICAL_PATH_SPT.getCode()
        };
    }

    /**
     * 获取算法统计信息
     *
     * @return 算法统计
     */
    public Map<String, Object> getAlgorithmStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalAlgorithms", algorithmMap.size());
        stats.put("recommendedAlgorithms", getRecommendedAlgorithms());
        stats.put("supportedAlgorithms", getSupportedAlgorithms());

        Map<String, String> algorithmDescriptions = new HashMap<>();
        for (ScheduleAlgorithmType type : ScheduleAlgorithmType.values()) {
            algorithmDescriptions.put(type.getCode(), type.getDescription());
        }
        stats.put("algorithmDescriptions", algorithmDescriptions);

        return stats;
    }
} 